# -*- coding: utf-8 -*-
from django.utils import simplejson as json

from tipfy import (RequestHandler, Response, RequestRedirect, abort,
                   cached_property, redirect, url_for)
from tipfy.ext.jinja2 import Jinja2Mixin
from tipfy.ext.auth import MultiAuthMixin, login_required, user_required
from tipfy.ext.session import AllSessionMixins, SessionMiddleware
from tipfy.ext.wtforms import Form, fields, validators
from tipfy.ext.auth.rpx import get_callback_url, RPXMixin

import logging

REQUIRED = validators.required()

class SignupForm(Form):
    username = fields.TextField('Username', validators=[REQUIRED])
    email = fields.TextField('Email', validators=[REQUIRED, validators.Email()])

class BaseHandler(RequestHandler, RPXMixin, Jinja2Mixin,
                  AllSessionMixins):
    middleware = [SessionMiddleware]

    def render_response(self, filename, **kwargs):
        self.request.context.update({
            'auth_session': self.auth_session,
            'current_user': self.auth_current_user,
            'current_url': self.request.url,
            'logout_url': self.auth_logout_url(),
            'rpx_url': get_callback_url(self.auth_session.get('_continue',
                            self.request.args.get('continue', self.request.url)))
        })
        if self.messages:
            self.request.context['messages'] = json.dumps(self.messages)

        return super(BaseHandler, self).render_response(filename, **kwargs)

class RPXDemoHandler(BaseHandler):
    def get(self, **kwargs):
        return self.render_response('index.html')

class LoginHandler(BaseHandler):
    def get(self, **kwargs):
        return self.render_response('auth/login.html')

class LogoutHandler(BaseHandler):
    def get(self, **kwargs):
        self.auth_logout()
        return redirect(self.request.args.get('continue', '/'))

class SignupHandler(BaseHandler):
    @login_required
    def get(self, **kwargs):
        redirect_url = self.auth_session.get('_continue',
                            self.request.args.get('continue', '/'))
        if self.auth_current_user:
            return redirect(redirect_url)
        form = SignupForm(**self.auth_session)
        return self.render_response('auth/signup.html', form=form)

    @login_required
    def post(self, **kwargs):
        redirect_url = self.auth_session.get('_continue',
                            self.request.args.get('continue', '/'))
        if self.auth_current_user:
            return redirect(redirect_url)

        if self.form.validate():
            auth_id = self.auth_session.get('id')
            user = self.auth_create_user(username=self.form.username.data,
                                         auth_id = auth_id,
                                         email=self.form.email.data)
            if user:
                self.auth_set_session(user.auth_id, user.session_id, '1')
                logging.info("Creating Login: %s" % dict(self.auth_session))
                self.auth_create_login(user=user, **dict(self.auth_session))
                self.set_message('success', 'You are now registered. Welcome.',
                                 flash=True, life=5)
                return redirect(redirect_url)
            else:
                self.set_message('error', 'This nickname is already in use.',
                                 life=None)
                return self.get(**kwargs)

        self.set_message('error', 'A problem occurred. Please correct the '
                         'errors listed in the form.', life=None)
        return self.get(**kwargs)

    @cached_property
    def form(self):
        return SignupForm(self.request)

class RPXAuthHandler(BaseHandler):
    def get(self, **kwargs):
        return self.render_response('index.html')

    def post(self, **kwargs):
        self.auth_session['_continue'] = self.auth_session.get('_continue',
                                               self.request.args.get('continue', '/'))
        return self.get_authenticated_user(self._on_auth)

    def _on_auth(self, login_data):
        if not login_data:
            abort(403)

        if self.auth_current_user:
            self.auth_create_login(user=self.auth_current_user, **login_data)
            self.set_message('success', 'Login added.', flash=True, life=5)
            return redirect(self.auth_session.pop('_continue', '/'))

        auth_id = "rpx|%s" % login_data.get('username', '')
        logging.info("Third party auth: %s" % login_data)
        user = self.auth_login_with_third_party(auth_id, remember=True, **login_data)
        logging.info("Logged in with user: %s" % user)
        if user:
            return redirect(self.auth_session.pop('_continue', '/'))
        else:
            return redirect(url_for('auth/signup'))
